﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace BoneAnimationProt
{
    public class UIScreen : UIElement
    {
        public Texture2D background;

        public override void Draw(SpriteBatch _spriteBatch)
        {
            if (background != null)
            {
                Size = new Vector2(background.Width, background.Height);
                _spriteBatch.Draw(background, ElementRect, null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 1);
            }
            base.Draw(_spriteBatch);
        }
    }

    public class UITimeLine : UIElement
    {
        public event UIEvent OnMouseDown;
        public Texture2D markerTexture;
        public float startValue;
        public float endValue;
        public float markerPos;
        public float fixedMarkerIntervallSmall = 0.025f;
        public float fixedMarkerIntervallBig;

        public List<float> additionalMarkers;

        public UITimeLine()
        {
            additionalMarkers = new List<float>();
            fixedMarkerIntervallBig = fixedMarkerIntervallSmall * 4;
        }

        public override void Update(GameTime _gameTime)
        {
            if (InputHandler.LeftMouseClicked() && ElementRect.Contains((int)InputHandler.MousePosition.X, (int)InputHandler.MousePosition.Y))
            {
                markerPos = (InputHandler.MousePosition.X - Position.X) / (Size.X);
                if ((markerPos % fixedMarkerIntervallSmall) < fixedMarkerIntervallSmall / 5 || (markerPos % fixedMarkerIntervallSmall) > fixedMarkerIntervallSmall - fixedMarkerIntervallSmall / 5)
                    markerPos = fixedMarkerIntervallSmall * (int)Math.Round(markerPos / fixedMarkerIntervallSmall);
                if (OnMouseDown != null)
                    OnMouseDown(this, markerPos);
            }
            base.Update(_gameTime);
        }

        public override void Draw(SpriteBatch _spriteBatch)
        {
            foreach (float marker in additionalMarkers)
                _spriteBatch.Draw(markerTexture, Position + new Vector2(Size.X * ((marker - startValue) / (endValue - startValue)) - markerTexture.Width / 2, 0), null, Color.Blue,
                    0, Vector2.Zero, Vector2.One, SpriteEffects.None, 0.9f);

            float drawPos = 0;
            while (drawPos <= 1)
            {
                float posY = Size.Y/2;
                float scaleY = 0.5f;
                if ((decimal)drawPos % (decimal)fixedMarkerIntervallBig == 0)
                {
                    posY = Size.Y / 4;
                    scaleY = 0.75f;
                }
                _spriteBatch.Draw(markerTexture, Position + new Vector2(Size.X * drawPos - markerTexture.Width / 2, posY), null, Color.Black,
                    0, Vector2.Zero, new Vector2(0.5f, scaleY), SpriteEffects.None, 0.95f);
                drawPos += fixedMarkerIntervallSmall;
                drawPos = (float)Math.Round(drawPos, 3);
            }

            _spriteBatch.Draw(markerTexture, Position + new Vector2(Size.X * ((markerPos - startValue) / (endValue - startValue)) - markerTexture.Width / 2, 0), Color.Red);
            base.Draw(_spriteBatch);
        }        
    }

    public class UIToggleButton : UIButton
    {
        public override void Update(GameTime _gameTime)
        {
            if (ElementRect.Contains((int)InputHandler.MousePosition.X, (int)InputHandler.MousePosition.Y))
            {
                if (InputHandler.LeftMouseDown())
                    IsDown = !IsDown;
            }
        }
    }

    public class UITreeView : UIElement
    {
        JointAnimation anim;
        SpriteFont font;
        int indent = 10;
        int offset = 10;

        public UITreeView(JointAnimation _anim, SpriteFont _font)
        {
            anim = _anim;
            font = _font;
        }

        public override void Draw(SpriteBatch _spriteBatch)
        {
            DrawJoint(anim.joints[0], 0, 0, _spriteBatch);
            base.Draw(_spriteBatch);
        }

        public int DrawJoint(Joint _joint, int _layer, int _yOffset, SpriteBatch _batch)
        {
            int currentYOffset = _yOffset + offset;
            _batch.DrawString(font, _joint.Name, Position + new Vector2(indent * _layer, currentYOffset), Color.Black);
            

            foreach (Joint child in _joint.Childs)
            {
                currentYOffset = DrawJoint(child, _layer + 1, currentYOffset + offset, _batch);
            }
            return currentYOffset;           
        }
    }

    public class UIElement
    {
        public delegate void UIEvent(UIElement _sender, object _message);
        public Vector2 Position { get { return Parent != null ? Parent.Position + RelativePosition : RelativePosition; } }
        public Vector2 Size;

        public Vector2 RelativePosition;
        public Rectangle ElementRect { get { return new Rectangle((int)Position.X, (int)Position.Y, (int)Size.X, (int)Size.Y); } }
        public List<UIElement> Childs;
        public UIElement Parent;

        public UIElement()
        {
            Childs = new List<UIElement>();
        }

        public virtual void Update(GameTime _gameTime)
        {
            foreach (UIElement ele in Childs)
                ele.Update(_gameTime);
        }

        public virtual void Draw(SpriteBatch _spriteBatch)
        {
            foreach (UIElement ele in Childs)
                ele.Draw(_spriteBatch);
        }
    }

    public class UIButton : UIElement
    {
        public event UIEvent ButtonPressed;
        public Texture2D textureUp;
        public Texture2D textureDown;
        public bool IsDown;

        public override void Update(GameTime _gameTime)
        {
            if (ElementRect.Contains((int)InputHandler.MousePosition.X, (int)InputHandler.MousePosition.Y))
            {
                if (InputHandler.LeftMouseDown())
                    IsDown = true;

                if (InputHandler.LeftMouseUp() && IsDown)
                {
                    IsDown = false;
                    if (ButtonPressed != null)
                        ButtonPressed(this, null);
                }
            }
            else
            {
                IsDown = false;
            }
            base.Update(_gameTime);                        
        }

        public override void Draw(SpriteBatch _spriteBatch)
        {
            Size = new Vector2(textureUp.Width, textureUp.Height);
            if (IsDown)
            {
                _spriteBatch.Draw(textureDown, ElementRect, Color.Gray );
            }
            else
            {
                _spriteBatch.Draw(textureUp, ElementRect, Color.White);
            }
            base.Draw(_spriteBatch);
        } 
        
    }

    public class UI
    {

    }
}
